<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>

    // ES5 传统的对象取值  => 对象上取值 给对应的变量赋值
    // var zhang = {
    //     name: "张三",
    //     age: 18,
    //     height: "177cm",
    //     weight: "67kg",
    // }

    // var name = zhang.name; //从对象中取值 对变量进行赋值
    // var age = zhang.age; //从对象中取值 对变量进行赋值
    // var height = zhang.height; //从对象中取值 对变量进行赋值
    // var weight = zhang.weight; //从对象中取值 对变量进行赋值

    // ES6 允许按照一定模式，从数组和对象中提取值，对变量进行赋值，这被称为解构（Destructuring）。
    // 本质上，这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值

    // 对象解构 => 对应键名解构
    // var zhang = { name: "张三", age: 18, height: "177cm", weight: "67kg" }

    // 完全解构
    // var { name, age, height, weight } = { name: "张三", age: 18, height: "177cm", weight: "67kg" };
    // console.log(name, age, height, weight);


    // 不完全解构  等号左边只匹配等号右边一部分
    // var { age, name } = { name: "张三", age: 18, height: "177cm", weight: "67kg" };
    // console.log(name, age);


    // 解构不成功 =>  返回undefined
    // var { name, age, isStudy, height, weight } = { name: "张三", age: 18, height: "177cm", weight: "67kg" };
    // console.log(name, age, height, weight, isStudy);

    // 解构过程中可以给变量设置默认值
    // isStudy = isStudy === undefined ? true : isStudy
    // var { name, age, isStudy = true, height, weight } = { name: "张三", age: 18, height: "177cm", weight: "67kg" };
    // console.log(name, age, height, weight, isStudy);


    // 对象解构需要注意:  不能对 null和undefined进行解构

    // var { a, toString, toFixed } = 1;   // new Number(1)
    // console.log(a, toString, toFixed);

    // var num = 1;
    // console.log(num.toString());
    // console.log(num.toFixed(2));


    // var { a } = null;
    // console.log(a);

    // var { a } = undefined;
    // console.log(a);


    // 对象解构高级:

    // (1) Rest参数 (剩余参数)
    // var zhang = { name: "张三", age: 18, height: "177cm", weight: "67kg" };
    // var { name, age, ...info } = { name: "张三", age: 18, height: "177cm", weight: "67kg" }
    // name => "张三"
    // age => 18
    // ...info => height: "177cm", weight: "67kg"  逆向推论: {height: "177cm", weight: "67kg"}
    // console.log(name, age, info);

    // 报错 => Rest element must be last element

    // var { name, weight, ...info } = { name: "张三", age: 18, height: "177cm", weight: "67kg" }
    // console.log(name, info, weight);


    // (2) 如果需要对 对象中的属性进行二次解构 => 对应键名解构键值

    // 对象中嵌套对象和数组
    var zhang = {
        name: "张三",
        age: 18,
        info: {
            height: "177cm",
            weight: "67kg"
        },
        hobby: ["sing", "dance", "rap"]
    }


    // 分步解构
    // var { name, age, info, hobby } = zhang
    // console.log(name, age, info, hobby);
    // info = {height: "177cm", weight: "67kg" }
    // hobby =  ["sing", "dance", "rap"]

    // var { height, weight } = info;
    // console.log(height, weight);

    // var [h1, h2, h3] = hobby;
    // console.log(h1, h2, h3);


    // 一步到位: 
    // var { name, age, info, hobby } = zhang
    // var { name, age, info: info, hobby: hobby } = zhang
    var { name, age, "info": { height, weight }, "hobby": [h1, h2, h3] } = zhang
    console.log(name, age, height, weight, h1, h2, h);



    // 练习: 

    let obj = {
        p: [
            'Hello',
            { y: 'World' }
        ]
    };

    const node = {
        loc: {
            start: {
                line: 1,
                column: 5
            }
        }
    };

</script>

</html>